package com.example.springboot.controller;

import com.example.springboot.annotation.MethodPermission;
import com.example.springboot.common.PageBean.PageBean;
import com.example.springboot.common.Result.Result;
import com.example.springboot.common.exception.ServiceException;
import com.example.springboot.common.utils.ThrowUtil.ThrowUtil;
import com.example.springboot.entity.dto.SetRoleDto;
import com.example.springboot.entity.UserRole;
import com.example.springboot.entity.Role;
import com.example.springboot.entity.User;
import com.example.springboot.service.RoleService;
import com.example.springboot.service.UserService;
import com.example.springboot.service.UserRoleService;
import com.example.springboot.common.utils.ExcelUtil.ExcelUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/acl/user")
public class UserController {

    @Autowired
    public UserService userService;

    @Autowired
    public RoleService roleService;

    @Autowired
    public UserRoleService userRoleService;

    /**
     * 分页查看（多条件就接着加到参数里面）
     *
     * @param pageNum
     * @param pageSize
     * @param name
     * @return
     */
    @MethodPermission("user_query")
    @GetMapping("/{pageNum}/{pageSize}")
    public Result<?> Page(@PathVariable int pageNum, @PathVariable int pageSize, String name) {
        PageBean pageBean = userService.page(pageNum, pageSize, name);
        return Result.success(pageBean);
    }

    /**
     * 添加用户
     *
     * @param user
     * @return
     */
    @MethodPermission("user_add")
    @PostMapping("/save")
    public Result<?> add(@RequestBody User user) {
        userService.add(user);
        return Result.success();
    }

    /**
     * 更新用户(更新关联表中的数据（关联表存了用户名）)
     *
     * @param user
     * @return
     */
    @MethodPermission("user_update")
    @PutMapping("/update")
    public Result<?> update(@RequestBody User user) {
        List<UserRole> userRoles = userRoleService.getUserRoleByUserId(user.getId());
        userRoles.forEach(item -> {
            item.setUserName(user.getName());
            userRoleService.update(item);
        });
        userService.update(user);
        return Result.success();
    }

    /**
     * 删除用户(删除关系表中的数据)
     *
     * @param id
     * @return
     */
    @MethodPermission("user_delete")
    @DeleteMapping("/remove/{id}")
    public Result<?> delete(@PathVariable Long id) {
        ThrowUtil.throwIf(id == 1, "admin无法删除");
        userRoleService.deleteAllRoleByUserId(id);
        userService.delete(id);
        return Result.success();
    }


    /**
     * 批量删除(删除关系表中的数据)
     *
     * @param ids
     * @return
     */
    @MethodPermission("user_delete")
    @DeleteMapping("/batchRemove")
    public Result<?> deleteAll(@RequestBody List<Long> ids) {
        ids.forEach(item -> {
            ThrowUtil.throwIf(item == 1, "admin无法删除");
            userRoleService.deleteAllRoleByUserId(item);
        });
        userService.deleteAll(ids);
        return Result.success();
    }

    /**
     * 获取全部职位,和当前账号拥有的职位接口(没有用关系表)
     * @param id
     * @return
     */
    /*@GetMapping("/toAssign/{id}")
    public Result<?> GetRole(@PathVariable Long id){
        Map<String,List> map=new HashMap<>();
        List<Role> assignRoles = roleService.getRoleByUserId(id);
        List<Role> allRolesList = roleService.getAllRole();
        map.put("assignRoles",assignRoles);
        map.put("allRolesList",allRolesList);
        return Result.success(map);
    }*/

    /**
     * 获取全部职位,和当前账号拥有的职位接口(用关系表)
     *
     * @param id
     * @return
     */
    @GetMapping("/toAssign/{id}")
    public Result<?> GetRole(@PathVariable Long id) {
        Map<String, List> map = new HashMap<>();
        List<Long> roleId = userRoleService.getRoleIdByUserId(id);
        //guigo-oa是此逻辑，先查全部，然后用roleId集合来跟全部进行判断，如果全部里面包含roleId，就直接返回role集合,不用在查数据库了
        //我这里是每一条roleId都查数据库,比较繁琐
        List<Role> assignRoles = roleId.stream().map(item -> {
            return roleService.getRoleById(item);
        }).collect(Collectors.toList());
        List<Role> allRolesList = roleService.getAllRole();
        map.put("assignRoles", assignRoles);
        map.put("allRolesList", allRolesList);
        return Result.success(map);
    }

    /**
     *  分配角色，保存(没用关系表)
     * @param setRoleDto
     * @return
     */
    /*@PostMapping("/doAssignRole")
    public Result<?> SetRole(@RequestBody SetRoleDto setRoleDto){
        List<Role> roles = roleService.getRoleByIds(setRoleDto.getRoleIdList());
        String roleName;
        if(StringUtils.isEmpty(roles)){
            roleName = "";
        }else{
            List<String> role = roles.stream().map(item -> {
                return item.getRoleName();
            }).collect(Collectors.toList());
            roleName = String.join(",", role);
        }
        User user = userService.getById(setRoleDto.getUserId());
        user.setRoleName(roleName);
        userService.update(user);
        return Result.success();
    }*/


    /**
     * 分配角色，保存(用关系表)
     *
     * @param setRoleDto
     * @return
     */
    @MethodPermission("user_update")
    @PostMapping("/doAssignRole")
    public Result<?> SetRole(@RequestBody SetRoleDto setRoleDto) {
        User user = userService.getById(setRoleDto.getUserId());
        UserRole userRole = new UserRole();
        userRoleService.deleteAllRoleByUserId(setRoleDto.getUserId());
        List<String> roleNames = setRoleDto.getRoleIdList().stream().map(item -> {
            Role role = roleService.getRoleById(item);
            userRole.setUserId(user.getId());
            userRole.setUserName(user.getName());
            userRole.setRoleId(role.getId());
            userRole.setRoleName(role.getRoleName());
            userRoleService.add(userRole);
            return userRole.getRoleName();
        }).collect(Collectors.toList());
        String roleName = String.join(",", roleNames);
        user.setRoleName(roleName);
        userService.update(user);
        return Result.success();
    }

    /**
     * 导出用户数据
     */
    @MethodPermission("user_add")
    @GetMapping("/export")
    public void Export(HttpServletResponse response) {
        ExcelUtil<User> excelUtil = new ExcelUtil<>();
        List<User> list = userService.list();
        excelUtil.exportExcel(list, response);
    }

    /**
     * 导入用户数据
     *
     * @param file
     * @return
     * @throws Exception
     */
    @MethodPermission("user_add")
    @PostMapping("/import")
    public Result<?> Import(MultipartFile file) throws Exception {
        ExcelUtil<User> excelUtil = new ExcelUtil<User>(User.class);
        List<User> list = excelUtil.importExcel(file.getInputStream());
        list.forEach(item ->
                userService.add(item)
        );
        return Result.success();
    }
}
